package com.titaniume.activitiweb.controller;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.titaniume.activitiweb.SecurityUtil;
import com.titaniume.activitiweb.pojo.UserInfoBean;
import com.titaniume.activitiweb.util.AjaxResponse;
import com.titaniume.activitiweb.util.GlobalConfig;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

/**
 * @ProjectName: activiti7_workflow
 * @Package: com.titaniume.activitiweb.controller
 * @ClassName: ActivitiHistoryController
 * @Author: huangrenfei
 * @Description: 历史
 * @Date: 2021/11/16 11:32
 * @Version: 1.0
 */
@RestController
@RequestMapping("/activitiHistory")
public class ActivitiHistoryController {

    @Autowired
    private SecurityUtil securityUtil;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private RepositoryService repositoryService;

    //用户历史任务
    @GetMapping(value = "/getInstancesByUserName")
    public AjaxResponse getInstancesByUserName(@AuthenticationPrincipal UserInfoBean userInfoBean, @RequestParam("userName") String userName) {
        try {

            List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
                    .orderByHistoricTaskInstanceEndTime().desc()
                    .taskAssignee(userInfoBean.getUsername())
                    .list();


            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(),
                    list);
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "获取用户历史任务失败",
                    e.toString());
        }
    }


    //根据流程实例ID查询任务
    @GetMapping(value = "/getInstanceByPiID")
    public AjaxResponse getInstanceByPiID(@RequestParam("piID") String piID) {
        try {

            List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
                    .orderByHistoricTaskInstanceEndTime().desc()
                    .processInstanceId(piID)
                    .list();
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(),
                    list);
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "获取历史任务失败",
                    e.toString());
        }
    }


    //高亮显示流程历史
    @GetMapping(value = "/getHighLine")
    public AjaxResponse getHighLine(@RequestParam("instanceID") String instanceID,
                                    @AuthenticationPrincipal UserInfoBean userInfoBean) {
        try {

            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(instanceID)
                    .singleResult();

            //读取bpmn
            BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());
            Process process = bpmnModel.getProcesses().get(0);
            //获取所有流程FlowElement的信息
            Collection<FlowElement> flowElements = process.getFlowElements();
            HashMap<String, String> map = new HashMap<>();
            for (FlowElement flowElement : flowElements) {
                //判断是否是线条
                if (flowElement instanceof SequenceFlow) {
                    SequenceFlow sequenceFlow = (SequenceFlow) flowElement;
                    String sourceRef = sequenceFlow.getSourceRef();
                    String targetRef = sequenceFlow.getTargetRef();
                    map.put(sourceRef + targetRef, sequenceFlow.getId());
                }

            }

            //获取全部历史流程节点
            List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()
                    .processInstanceId(instanceID)
                    .list();
            //各历史节点两两组成key
            HashSet<String> keyList = new HashSet<>();
            for (HistoricActivityInstance i : list) {
                for (HistoricActivityInstance j : list) {
                    if (i != j) {
                        keyList.add(i.getActivityId() + j.getActivityId());
                    }
                }
            }


            //高亮连线ID
            HashSet<String> highLine = new HashSet<>();
            keyList.forEach(s -> highLine.add(map.get(s)));


            //获取已经完成的节点
            List<HistoricActivityInstance> listFinished = historyService.createHistoricActivityInstanceQuery()
                    .processInstanceId(instanceID)
                    .finished()
                    .list();
            //已经完成的高亮节点
            HashSet<String> highPoint = new HashSet<>();
            listFinished.forEach(s -> highPoint.add(s.getActivityId()));


            //获取代表节点
            List<HistoricActivityInstance> listUnFinished = historyService.createHistoricActivityInstanceQuery()
                    .processInstanceId(instanceID)
                    .unfinished()
                    .list();
            //代办高亮节点
            HashSet<String> waitingToDo = new HashSet<>();
            listUnFinished.forEach(s -> waitingToDo.add(s.getActivityId()));


            //当前用户完成的任务
            String AssigneeName = null;
            if (GlobalConfig.Test) {
                AssigneeName = "bajie";
            } else {
                AssigneeName = userInfoBean.getUsername();
            }

            List<HistoricTaskInstance> taskInstanceList = historyService.createHistoricTaskInstanceQuery()
                    .taskAssignee(AssigneeName)
                    .processInstanceId(instanceID)
                    .finished()
                    .list();
            //代办高亮节点
            HashSet<String> iDo = new HashSet<>();
            taskInstanceList.forEach( s -> iDo.add(s.getTaskDefinitionKey()));
            HashMap<String, Object> hashMap = new HashMap<String, Object>();
            hashMap.put("highPoint",highPoint);
            hashMap.put("highLine",highLine);
            hashMap.put("waitingToDo",waitingToDo);
            hashMap.put("iDo",iDo);


            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(),
                    hashMap);
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "获取高亮显示流程历史失败",
                    e.toString());
        }
    }


}
